﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MapColoring.MontadorMapa
{
    /// <summary>
    /// Classe com métodos estáticos de Geometria
    /// </summary>
    public static class Geometria
    {
        /// <summary>
        /// Calcula distância entre os pontos p1 e p2
        /// </summary>
        /// <param name="p1">Ponto 1</param>
        /// <param name="p2">Ponto 2</param>
        /// <returns>Distância entre os pontos</returns>
        public static double Distancia(Ponto p1, Ponto p2)
        {
            return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
        }

        /// <summary>
        /// Retorna verdadeiro se o segmento p1p2 intercepta o segmento p3p4
        /// </summary>
        /// <param name="p1">Ponto 1, parte do segmento 1 de reta</param>
        /// <param name="p2">Ponto 2, parte do segmento 1 de reta</param>
        /// <param name="p3">Ponto 3, parte do segmento 2 de reta</param>
        /// <param name="p4">Ponto 4, parte do segmento 2 de reta</param>
        /// <returns>true, se p1p2 intercepta p3p4</returns>
        public static bool Intercepta(Ponto p1, Ponto p2, Ponto p3, Ponto p4)
        {
            // Os segmentos se interceptam se p3 e p4 estão em lados opostos em relação a p1 e p2,
            // e p1 e p2 estão em lados opostos em relação a p3 e p4
            return (((ProdutoVetorial(p2, p3, p1) * ProdutoVetorial(p2, p4, p1)) < 0)
                 && ((ProdutoVetorial(p4, p1, p3) * ProdutoVetorial(p4, p2, p3)) < 0));
        }

        /// <summary>
        /// Calcula o produto vetorial entre os segmentos p3p1 e p3p2 (em R2)
        /// </summary>
        /// <param name="p1">Ponto 1, parte do segmento 1 de reta</param>
        /// <param name="p2">Ponto 2, parte do segmento 1 de reta</param>
        /// <param name="p3">Ponto 3, ponto de referência para os dois segmentos</param>
        /// <returns>p3p1 x p3p2</returns>
        public static double ProdutoVetorial(Ponto p1, Ponto p2, Ponto p3)
        {
            return (((p1.X - p3.X) * (p2.Y - p3.Y)) - ((p2.X - p3.X) * (p1.Y - p3.Y)));
        }

        /// <summary>
        /// Verifica se triangulos t1 e t2 são adjacentes, isto é, possuem uma aresta em comum
        /// </summary>
        /// <param name="t1">Triangulo 1</param>
        /// <param name="t2">Triangulo 2</param>
        /// <returns>true, se triângulos t1 e t2 forem adjacentes</returns>
        public static bool SaoTriangAdjacentes(Triangulo t1, Triangulo t2)
        {
            bool achou1 = false;
            int indice1 = -1;

            //Procura primeiro ponto em comum
            for (int i = 0; i < t1.Vertices.Length; i++)
            {
                for (int j = 0; j < t2.Vertices.Length; j++)
                {
                    if (t1.Vertices[i].Equals(t2.Vertices[j]))
                    {
                        achou1 = true;
                        indice1 = i;
                        break;
                    }
                }

                if (achou1)
                    break;
            }

            if (!achou1)
                return false;

            //Procura segundo ponto em comum
            for (int i = indice1 + 1; i < t1.Vertices.Length; i++)
            {
                for (int j = 0; j < t2.Vertices.Length; j++)
                {
                    if (t1.Vertices[i].Equals(t2.Vertices[j]))
                        return true;
                }
            }

            return false;
        }
    }
}
